Passed
Push — master ( 0ea8b8...f91622 )
by M. Mikkel
09:09
created

cpfieldinspect.js ➔ getLivePreview   B

Complexity

Conditions 6

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 6
c 0
b 0
f 0
dl 0
loc 8
rs 8.6666
1
/** global: Craft */
2
/** global: Garnish */
3
/** global: $ */
4
5
(function (window) {
6
7
    if (!window.Craft || !window.Garnish || !window.$) {
8
        return;
9
    }
10
11
    Craft.CpFieldInspectPlugin = {
12
13
        elementEditors: {},
14
15
        settings: {
16
            settingsClassSelector: 'cp-field-inspect-settings',
17
            infoClassSelector: 'cp-field-inspect-info',
18
            redirectKey: '_CpFieldInspectRedirectTo',
19
            actionInputKeys: [
20
                '[value="fields/save-field"]',
21
                '[value="sections/save-entry-type"]',
22
                '[value="globals/save-set"]',
23
                '[value="categories/save-group"]',
24
                '[value="volumes/save-volume"]',
25
                '[value="commerce/product-types/save-product-type"]'
26
            ]
27
        },
28
29
        init: function (data) {
30
31
            var _this = this;
32
33
            this.data = data;
34
            this.setPathAndRedirect();
35
36
            // Initialize Live Preview support
37
            var now = new Date().getTime(),
38
                livePreviewPoller = (function getLivePreview() {
39
                    if (Craft.livePreview) {
40
                        Craft.livePreview.on('enter', this.onLivePreviewEnter.bind(this));
41
                        Craft.livePreview.on('exit', this.onLivePreviewExit.bind(this));
42
                    } else if (new Date().getTime() - now < 2000) {
43
                        Garnish.requestAnimationFrame(livePreviewPoller);
44
                    }
45
                }).bind(this);
46
47
            livePreviewPoller();
48
49
            // Poll for address bar change
50
            var url = window.location.href;
51
            this.addressBarChangeInterval = setInterval(function () {
52
                var newUrl = window.location.href;
53
                if (newUrl === url) {
54
                    return;
55
                }
56
                url = newUrl;
57
                try {
58
                    Craft.postActionRequest('cp-field-inspect/default/get-redirect-hash', { url: url }, $.proxy(function (response) {
59
                        this.data.redirectUrl = response.data || this.data.redirectUrl || null;
60
                    }, _this));
61
                } catch (error) {
62
                    console.error(error);
63
                }
64
            }, 100);
65
66
            // Add event handlers
67
            Garnish.$doc
68
                .on('click', '[data-cpfieldlinks-sourcebtn]', $.proxy(this.onSourceEditBtnClick, this))
69
                .on('click', '.matrix .btn.add, .matrix .btn[data-type]', $.proxy(this.onMatrixBlockAddButtonClick, this))
70
                .on('keydown', $.proxy(this.onKeyDown, this))
71
                .on('keyup', $.proxy(this.onKeyUp, this))
72
                .ajaxComplete($.proxy(this.onAjaxComplete, this));
73
74
            window.onblur = this.onWindowBlur;
75
76
            Garnish.requestAnimationFrame($.proxy(this.addFieldLinks, this));
77
        },
78
79
        initElementEditor: function () {
80
            var now = new Date().getTime(),
81
                doInitElementEditor = $.proxy(function () {
82
                    var timestamp = new Date().getTime(),
83
                        $elementEditor = $('.elementeditor:last'),
84
                        $hud = $elementEditor.length > 0 ? $elementEditor.closest('.hud') : false,
85
                        elementEditor = $hud && $hud.length > 0 ? $hud.data('elementEditor') : false;
86
                    if (elementEditor && elementEditor.hud) {
87
                        this.elementEditors[elementEditor._namespace] = elementEditor;
88
                        elementEditor.hud.on('hide', $.proxy(this.destroyElementEditor, this, elementEditor));
89
                        Garnish.requestAnimationFrame($.proxy(this.addFieldLinks, this));
90
                    } else if (timestamp - now < 2000) { // Poll for 2 secs
91
                        Garnish.requestAnimationFrame(doInitElementEditor);
92
                    }
93
                }, this);
94
            doInitElementEditor();
95
        },
96
97
        destroyElementEditor: function (elementEditor) {
98
            if (this.elementEditors.hasOwnProperty(elementEditor._namespace)) {
99
                delete this.elementEditors[elementEditor._namespace];
100
            }
101
        },
102
103
        setPathAndRedirect: function () {
104
            var redirectTo = Craft.getLocalStorage(this.settings.redirectKey);
105
            if (redirectTo) {
106
                var $actionInput = $('input[type="hidden"][name="action"]').filter(this.settings.actionInputKeys.join(','));
107
                var $redirectInput = $('input[type="hidden"][name="redirect"]');
108
                if ($actionInput.length > 0 && $redirectInput.length > 0) {
109
                    $redirectInput.attr('value', redirectTo);
110
                }
111
                // Override the new save shortcut behaviour in Craft 3.5.10
112
                var $primaryForm = Craft.cp.$primaryForm;
113
                if (
114
                    $primaryForm.length &&
115
                    $primaryForm.find('input[name="action"]').val() === 'fields/save-field' &&
116
                    Garnish.hasAttr($primaryForm, 'data-saveshortcut') &&
117
                    !!Craft.cp.submitPrimaryForm
118
                ) {
119
                    Garnish.shortcutManager.unregisterShortcut({ keyCode: Garnish.S_KEY, ctrl: true });
120
                    Garnish.shortcutManager.registerShortcut({ keyCode: Garnish.S_KEY, ctrl: true }, () => {
121
                        Craft.cp.submitPrimaryForm({ redirect: redirectTo, retainScroll: false });
122
                    });
123
                    var submitBtn = ($primaryForm.find('.btn.submit.menubtn').data() || {}).menubtn || null;
124
                    if (submitBtn && submitBtn.menu) {
125
                        $(submitBtn.menu.$options[0]).find('span.shortcut').remove();
126
                    }
127
                }
128
            }
129
            Craft.setLocalStorage(this.settings.redirectKey, null);
130
        },
131
132
        addFieldLinks: function () {
133
134
            var targets = [$(this.getFieldContextSelector())];
135
136
            if (this.elementEditors && Object.keys(this.elementEditors).length) {
137
                for (var key in this.elementEditors) {
138
                    if (this.elementEditors.hasOwnProperty(key)) {
139
                        targets.push(this.elementEditors[key].$form);
140
                    }
141
                }
142
            }
143
144
            if (!targets.length) {
145
                return;
146
            }
147
148
            var _this = this;
149
150
            for (var i = 0; i < targets.length; ++i) {
151
152
                var $target = targets[i];
153
                if (!$target || !$target.length) {
154
                    continue;
155
                }
156
157
                var $copyFieldHandleButtons = $target.find('.field .heading [id$=-field-attribute].code:not([data-cpfieldlinks-inited])');
158
                $copyFieldHandleButtons.each(function () {
159
160
                    var $btn = $(this);
161
                    $btn.attr('data-cpfieldlinks-inited', true);
162
163
                    var rootField = $btn.parents('.field').get().slice(-1).pop();
164
                    var parentField = $btn.closest('.field');
165
                    if (!rootField || !parentField) {
166
                        return;
167
                    }
168
169
                    var field;
170
                    var rootFieldType = $(rootField).data('type');
171
172
                    switch (rootFieldType) {
173
                        case 'benf\\neo\\Field':
174
                            field = parentField;
175
                            break;
176
                        default:
177
                            field = rootField;
178
                    }
179
180
                    var fieldId = _this.getFieldId(field);
181
                    if (!fieldId) {
182
                        return;
183
                    }
184
185
                    $btn
186
                        .append('<span data-icon="settings" title="' + (_this.data.editFieldBtnLabel || 'Edit field settings') + '" />')
187
                        .on('click', '[data-icon="settings"]', function (e) {
188
                            e.preventDefault();
189
                            e.stopPropagation();
190
                            _this.redirectToFieldSettings(fieldId);
191
                        });
192
193
                }).on('mouseleave', function () {
194
                    $(this).blur();
195
                });
196
197
            }
198
        },
199
200
        doRedirect: function (href) {
201
            if (this.ctrlKeyDown) {
202
                window.open(href);
203
            } else {
204
                Craft.setLocalStorage(this.settings.redirectKey, this.data.redirectUrl || null);
205
                window.location.href = href;
206
            }
207
        },
208
209
        redirectToFieldSettings: function (fieldId) {
210
            var href = Craft.CpFieldInspectPlugin.data.baseEditFieldUrl + '/' + fieldId;
211
            this.doRedirect(href);
212
        },
213
214
        getFieldId: function (field) {
215
            var id = $(field).attr('id');
216
            if (!id) {
217
                return null;
218
            }
219
            var segments = id.split('-');
220
            if (segments.length < 3) {
221
                return null;
222
            }
223
            var handle = segments[segments.length - 2];
224
            return (this.data.fields || {})[handle] || null;
225
        },
226
227
        getFieldContextSelector: function () {
228
            if (this.isLivePreview) {
229
                return '.lp-editor';
230
            }
231
            return '#main';
232
        },
233
234
        onLivePreviewEnter: function () {
235
            this.isLivePreview = true;
236
            Garnish.requestAnimationFrame($.proxy(this.addFieldLinks, this));
237
        },
238
239
        onLivePreviewExit: function () {
240
            this.isLivePreview = false;
241
            Garnish.requestAnimationFrame($.proxy(this.addFieldLinks, this));
242
        },
243
244
        onSourceEditBtnClick: function (e) {
245
            e.preventDefault();
246
            this.doRedirect(e.target.href);
247
        },
248
249
        onMatrixBlockAddButtonClick: function () {
250
            Garnish.requestAnimationFrame($.proxy(this.addFieldLinks, this));
251
        },
252
253
        onKeyDown: function(e) {
254
            this.ctrlKeyDown = Garnish.isCtrlKeyPressed(e);
255
            setTimeout(function () {
256
                this.ctrlKeyDown = false;
257
            }, 1000);
258
        },
259
260
        onKeyUp: function () {
261
            this.ctrlKeyDown = false;
262
        },
263
264
        onWindowBlur: function () {
265
            this.ctrlKeyDown = false;
266
        },
267
268
        onAjaxComplete: function(e, status, requestData) {
269
            if (requestData.url.indexOf('switch-entry-type') === -1) {
270
                return;
271
            }
272
            const $entryTypeSelect = $('#entryType');
273
            if ($entryTypeSelect.length) {
274
                const typeId = $entryTypeSelect.val();
275
                $('[data-cpfieldlinks-sourcebtn][data-typeid]:not([data-typeid="' + typeId + '"]').hide();
276
                $('[data-cpfieldlinks-sourcebtn][data-typeid="' + typeId + '"]').show();
277
            }
278
            this.addFieldLinks();
279
        }
280
    };
281
282
} (window));
283